/**
 * Copyright (c) 2020-2021 ThunderSoft
 * All Rights Reserved by Thunder Software Technology Co., Ltd and its affiliates.
 * You may not use, copy, distribute, modify, transmit in any form this file
 * except in compliance with ThunderSoft in writing by applicable law.
 *
 */
/**
 * @file    turbox_timer.c
 * @brief   harmony bl platform timer adaptor
 * @details
 * @version 1.0 
 * @author  ThunderSoft  
 * @date    2020/12/3
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2020/12/3                ThunderSoft         Create it. 
 *
 */
#include "stdio.h"
#include "mtimer.h"
#include "los_reg.h"
#include "los_interrupt.h"
#include "los_tick.h"
#include "riscv_hal.h"
#include "soc.h"
#include "plic.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif

VOID MTimerCpuCycle(UINT32 *contHi, UINT32 *contLo)
{
    READ_UINT32(*contLo, MTIMER);
    READ_UINT32(*contHi, MTIMER + 4);
}

STATIC INLINE VOID UpdateMtimerCmp(UINT32 tick)
{
    unsigned long long timer;
    unsigned timerL, timerH;
    READ_UINT32(timerL, MTIMER);
    READ_UINT32(timerH, MTIMER + 4);
    timer = (UINT64)(((UINT64)timerH << 32) + timerL);
    timer += tick;
    WRITE_UINT32(0xffffffff, MTIMERCMP + 4);
    WRITE_UINT32((UINT32)timer, MTIMERCMP);
    WRITE_UINT32((UINT32)(timer >> 32), MTIMERCMP + 4);
}

STATIC VOID OsMachineTimerInterrupt(UINT32 sysCycle)
{
    OsTickHandler();
    UpdateMtimerCmp(sysCycle);
}

UINT32 MTimerTickInit(UINT32 period)
{
    UINT32 ret;

    ret = ArchHwiCreate(RISCV_MACH_TIMER_IRQ, 0x1, 0, OsMachineTimerInterrupt, period);
    if (ret != LOS_OK) {
        printf("turbox_sysClockInit fail\n");
        return ret;
    }

    WRITE_UINT32(0xffffffff, MTIMERCMP + 4);
    WRITE_UINT32(period, MTIMERCMP);
    WRITE_UINT32(0x0, MTIMERCMP + 4);

    PlicIrqPendingClear(RISCV_MACH_TIMER_IRQ);
    PlicIrqEnable(RISCV_MACH_TIMER_IRQ);
    HalIrqEnable(RISCV_MACH_TIMER_IRQ);

    return LOS_OK;
}

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
